package com.qianfeng.openapi.web.master.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qianfeng.openapi.web.master.bean.LayUITableVO;
import com.qianfeng.openapi.web.master.bean.LayUITreeVO;
import com.qianfeng.openapi.common.enums.OpenApiEnums;
import com.qianfeng.openapi.common.exception.OpenApiEx;
import com.qianfeng.openapi.web.master.mapper.RoleMapper;
import com.qianfeng.openapi.web.master.pojo.Menu;
import com.qianfeng.openapi.web.master.pojo.Role;
import com.qianfeng.openapi.web.master.service.MenuService;
import com.qianfeng.openapi.web.master.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Slf4j
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuService menuService;

    @Override
    public List<Role> findAll() {
        return roleMapper.findAll();
    }

    @Override
    public LayUITableVO findByNameAndPage(Integer page, Integer limit, String name) {
        //1. 分
        PageHelper.startPage(page,limit);
        //2. 查
        List<Role> roleList = roleMapper.findByName(name);
        //3. 封Info
        PageInfo<Role> pageInfo = new PageInfo<>(roleList);
        //4. 封VO
        LayUITableVO result = new LayUITableVO();
        result.setCount(pageInfo.getTotal());
        result.setData(pageInfo.getList());
        //5. 返
        return result;
    }


    @Override
    public List<LayUITreeVO> roleMenu(Integer roleId) {
        //1. 查询全部的菜单信息
        List<Menu> menuList = menuService.findAll();

        //2. 查询当前角色拥有的菜单信息
        List<Integer> menuIdList = roleMapper.findRoleMenuId(roleId);

        //3. 封装菜单信息,(判断是否是当前角色拥有的菜单,将checked设置为true)
        List<LayUITreeVO> data = new ArrayList<>();
        Map<Integer,LayUITreeVO> levelOne = new HashMap<>();
        Map<Integer,LayUITreeVO> levelTwo = new HashMap<>();


        // 将一级菜单和二级菜单(不是按钮)放到了levelOne和levelTwo中.
        for (Menu menu : menuList) {
            //1. 判断是否是一级菜单
            if(menu.getParentId() == null){
                // 是一级菜单
                LayUITreeVO vo = this.menuToLayUITreeVO(menu,menuIdList);
                // 将一级菜单信息,将id作为key放到Map中
                levelOne.put(menu.getId(),vo);
            }else{
                if(menu.getType() == 1){
                    // 是二级菜单,并且有子节点,先封装自己
                    LayUITreeVO vo = this.menuToLayUITreeVO(menu,menuIdList);
                    // 将二级菜单信息,将id作为key放到Map中
                    levelTwo.put(menu.getId(),vo);
                    // 将levelTwo中的内容插入到levelOne中
                    levelOne.get(menu.getParentId()).getChildren().add(vo);
                }else{
                    // 要么是三级菜单,或者是二级菜单但是已经是一个按钮
                    LayUITreeVO vo = this.menuToLayUITreeVO(menu,menuIdList);

                    LayUITreeVO levelTwoVO = levelTwo.get(menu.getParentId());
                    if(levelTwoVO != null){
                        // 是三级菜单
                        levelTwoVO.getChildren().add(vo);
                        continue;
                    }
                    levelOne.get(menu.getParentId()).getChildren().add(vo);
                }
            }
        }

        // 将levelOne封装到data中
        for (Map.Entry<Integer, LayUITreeVO> entry : levelOne.entrySet()) {
            data.add(entry.getValue());
        }

        //4. 返回数据
        return data;
    }

    @Override
    @Transactional
    public void assignMenu(Integer roleId, Integer[] menuId) {
        //1. 删除role_menu中的roleId数据
        roleMapper.deleteRoleMenuByRoleId(roleId);

        //2. 基于roleId和menuId添加到role_menu中
        if(menuId != null && menuId.length > 0) {
            int count = roleMapper.saveRoleIdAndMenuId(roleId, menuId);
            //3. 判断受影响行数和数组长度是否一致
            if(count != menuId.length){
                log.error("【给角色赋予菜单权限】 给角色添加菜单失败！！1 roleId = {}，menuId = {}",roleId, Arrays.toString(menuId));
                throw new OpenApiEx(OpenApiEnums.ROLE_MENU_ADD_ERROR);
            }
        }
    }


    private LayUITreeVO menuToLayUITreeVO(Menu menu,List<Integer> menuIdList){
        LayUITreeVO vo = new LayUITreeVO();
        Integer id = menu.getId();
        vo.setId(id);
        vo.setTitle(menu.getName());
        if(menuIdList.contains(id)){
            vo.setChecked(true);
        }
        return vo;
    }







}
